#include <QAction>
#include <QActionGroup>
#include <QCoreApplication>
#include <QApplication>
#include "widgets/menu_bar.h"
#include <rviz_custom_plugins/widgets/file_transfer_dialog.h>
#include <chrono>
#include <QFileDialog>
#include <QMessageBox>
#include <QDir>
#include <QLineEdit>
#include <QInputDialog>
#include <QProcess>


using namespace std::chrono_literals;
using rviz_custom_plugins::widgets::FileTransferDialog;


namespace gcs 
{


namespace widgets 
{


MenuBar::MenuBar(QWidget *parent) : QMenuBar(parent), context(nullptr) 
{
    
}

void MenuBar::initialize(DisplayContext * context) 
{
    this->context = context;

    projectManager = ProjectManager::getInstance();
    widgetManager = WidgetManager::getInstance();


    node = this->context->getRosNodeAbstraction().lock()->get_raw_node();
    oprCmdClient = node->create_client<ControlCmd>("visbot_opr_cmd");
    missionCfgClient = node->create_client<MissionCfg>("visbot_import_mission");
    // 创建主菜单
    projectMenu = addMenu("项目");
    // editMenu = addMenu("编辑");
    modeMenu = addMenu("任务模式");
    opMenu = addMenu("任务操作");
    manageMenu = addMenu("无人机管理");
    dataMenu = addMenu("数据处理");
    viewMenu = addMenu("视窗");
    helpMenu = addMenu("帮助");


    // 设置项目子菜单项
    QAction *newProjectAction = new QAction("新建项目", this);
    projectMenu->addAction(newProjectAction);
    QAction *loadProjectAction = new QAction("装入项目", this);
    projectMenu->addAction(loadProjectAction);
    QAction *saveProjectAction = new QAction("保存项目", this);
    projectMenu->addAction(saveProjectAction);
    QAction *closeProjectAction = new QAction("关闭项目", this);
    projectMenu->addAction(closeProjectAction);
    // QAction *exportProjectAction = new QAction("导出项目", this);
    // projectMenu->addAction(exportProjectAction);
    // QAction *importProjectAction = new QAction("导入项目", this);
    // projectMenu->addAction(importProjectAction);
    QAction *quitAction = new QAction("退出", this);
    projectMenu->addAction(quitAction);

    // 设置编辑子菜单项
    // QAction *undoAction = new QAction("撤销操作", this);
    // editMenu->addAction(undoAction);
    // QAction *redoAction = new QAction("重做操作", this);
    // editMenu->addAction(redoAction);

    // QMenu *selectObjMenu = editMenu->addMenu("选择对象类型");
    // QAction *pointCloudAction = new QAction("地图点云", this);
    // selectObjMenu->addAction(pointCloudAction);
    // QAction *waypointAction = new QAction("飞行航点", this);
    // selectObjMenu->addAction(waypointAction);
    // QAction *flyZoneAction = new QAction("探索空间", this);
    // selectObjMenu->addAction(flyZoneAction);
    // QAction *noflyZoneAction = new QAction("禁飞空间", this);
    // selectObjMenu->addAction(noflyZoneAction);
    // QAction *shootPointAction = new QAction("拍摄点", this);
    // selectObjMenu->addAction(shootPointAction);
    // QAction *shootFaceAction = new QAction("拍摄面", this);
    // selectObjMenu->addAction(shootFaceAction);
    // QAction *cancelAction = new QAction("取消选取", this);
    // selectObjMenu->addAction(cancelAction);

    // QAction* addObjAction = new QAction("增加对象", this);
    // editMenu->addAction(addObjAction);
    // QAction* editObjAction = new QAction("编辑对象", this);
    // editMenu->addAction(editObjAction);
    // QAction* delObjAction = new QAction("删除对象", this);
    // editMenu->addAction(delObjAction);

    // 设置任务模式子菜单项
    QAction* manualModeAction = new QAction("手动探索模式", this);
    manualModeAction->setCheckable(true);
    manualModeAction->setChecked(true);
    modeMenu->addAction(manualModeAction);

    QAction* autoExploreModeAction = new QAction("自动探索模式", this);
    autoExploreModeAction->setCheckable(true);
    modeMenu->addAction(autoExploreModeAction);

    QAction* autoPatrolModeAction = new QAction("自动巡查模式", this);
    autoPatrolModeAction->setCheckable(true);
    modeMenu->addAction(autoPatrolModeAction);

    QActionGroup* modeGroup = new QActionGroup(this);
    modeGroup->setExclusive(true);
    modeGroup->addAction(manualModeAction);
    modeGroup->addAction(autoExploreModeAction);
    modeGroup->addAction(autoPatrolModeAction);

    // 设置任务操作子菜单项
    QAction* snapshotAction = new QAction("拍摄照片", this);
    opMenu->addAction(snapshotAction);


    // 设置无人机管理子菜单项
    QAction* urlAction = new QAction("无人机配置", this);
    manageMenu->addAction(urlAction);
    QAction* upgradeAction = new QAction("固件升级", this);
    manageMenu->addAction(upgradeAction);
    QAction* rootAction = new QAction("重启无人机", this);
    manageMenu->addAction(rootAction);
    QAction* shutdownAction = new QAction("关闭无人机", this);
    manageMenu->addAction(shutdownAction);


    // 设置数据处理子菜单项
    QAction * uploadMapAction = new QAction("上传地图", this);
    dataMenu->addAction(uploadMapAction);

    QAction * uploadMissionAction = new QAction("上传任务", this);
    dataMenu->addAction(uploadMissionAction);

    // 设置视窗子菜单项
    QAction * displayPropAction = new QAction("三维导航属性窗口", this);
    displayPropAction->setCheckable(true);
    displayPropAction->setChecked(false);
    viewMenu->addAction(displayPropAction);

    QAction * gimbalVideoAction = new QAction("云台主摄视频窗口", this);
    gimbalVideoAction->setCheckable(true);
    gimbalVideoAction->setChecked(false);
    viewMenu->addAction(gimbalVideoAction);

    QAction * thermalVideoAction = new QAction("热成像视频窗口", this);
    thermalVideoAction->setCheckable(true);
    thermalVideoAction->setChecked(false);
    viewMenu->addAction(thermalVideoAction);

    QAction * globalVideoAction = new QAction("单目全局视频窗口", this);
    globalVideoAction->setCheckable(true);
    globalVideoAction->setChecked(false);
    viewMenu->addAction(globalVideoAction);

    QAction * uavWarningAction = new QAction("实时警告信息窗口", this);
    uavWarningAction->setCheckable(true);
    uavWarningAction->setChecked(false);
    viewMenu->addAction(uavWarningAction);

    // QAction * displayEditAction = new QAction("对象编辑窗口", this);
    // displayEditAction->setCheckable(true);
    // displayEditAction->setChecked(false);
    // viewMenu->addAction(displayEditAction);

    QAction * cmdAction = new QAction("任务操作窗口", this);
    cmdAction->setCheckable(true);
    cmdAction->setChecked(false);
    viewMenu->addAction(cmdAction);

    QAction * uavStatusAction = new QAction("飞行实时状态窗口", this);
    uavStatusAction->setCheckable(true);
    uavStatusAction->setChecked(false);
    viewMenu->addAction(uavStatusAction);

    // 设置帮助子菜单项

    connect(newProjectAction, &QAction::triggered, this, &MenuBar::createProjectBtnClicked);
    connect(loadProjectAction, &QAction::triggered, this, &MenuBar::loadProjectBtnClicked);
    connect(saveProjectAction, &QAction::triggered, this, &MenuBar::saveProjectBtnClicked);
    connect(closeProjectAction, &QAction::triggered, this, &MenuBar::closeProjectBtnClicked);

    connect(quitAction, &QAction::triggered, qApp, &QCoreApplication::quit);
    connect(uploadMapAction, &QAction::triggered, this, &MenuBar::uploadMapBtnClicked);
    connect(uploadMissionAction, &QAction::triggered, this, &MenuBar::uploadMissionBtnClicked);
    connect(snapshotAction, &QAction::triggered, this, &MenuBar::snapshotBtnClicked);

    connect(displayPropAction, &QAction::toggled, [&](bool checked) {
        widgetManager->setWidgetShow(WidgetManager::DISPLAY_PROPERTY_PANEL, checked);
    });

    connect(gimbalVideoAction, &QAction::toggled, [&](bool checked) {
        widgetManager->setWidgetShow(WidgetManager::GIMBAL_VIDEO_PANEL, checked);
    });
    
    connect(thermalVideoAction, &QAction::toggled, [&](bool checked) {
        widgetManager->setWidgetShow(WidgetManager::THERMAL_VIDEO_PANEL, checked);
    });

    connect(globalVideoAction, &QAction::toggled, [&](bool checked) {
        widgetManager->setWidgetShow(WidgetManager::GLOBAL_VIDEO_PANEL, checked);
    });

    connect(uavWarningAction, &QAction::toggled, [&](bool checked) {
        widgetManager->setWidgetShow(WidgetManager::UAV_WARNING_PANEL, checked);
    });

    // connect(displayEditAction, &QAction::toggled, [&](bool checked) {
    //     widgetManager->setWidgetShow(WidgetManager::DISPLAY_EDIT_PANEL, checked);
    // });

    connect(cmdAction, &QAction::toggled, [&](bool checked) {
        widgetManager->setWidgetShow(WidgetManager::COMMAND_PANEL, checked);
    });

    connect(uavStatusAction, &QAction::toggled, [&](bool checked) {
        widgetManager->setWidgetShow(WidgetManager::UAV_STATUS_PANEL, checked);
    });
    
    connect(projectManager, &ProjectManager::projectCreated, this, &MenuBar::handleProjectLoaded, Qt::DirectConnection);
    connect(projectManager, &ProjectManager::projectOpened, this, &MenuBar::handleProjectLoaded, Qt::DirectConnection);
    // connect(projectManager, &ProjectManager::projectSaved, this, &MenuBar::handleProjectSaved, Qt::DirectConnection);
    connect(projectManager, &ProjectManager::projectClosed, this, &MenuBar::handleProjectClosed, Qt::DirectConnection);

    
}


DisplayContext * MenuBar::getDisplayContext() const
{
    return context;
}


void MenuBar::createProjectBtnClicked()
{
    QString parentDir = QFileDialog::getExistingDirectory(
        this,
        "选择父目录",
        QDir::homePath(),
        QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks
    );

    if (parentDir.isEmpty())
        return;

    // 输入新文件夹名称
    bool ok = false;
    QString newFolderName = QInputDialog::getText(
        this,
        "新建项目",
        "请输入项目名称：",
        QLineEdit::Normal,
        "",
        &ok
    );

    if (!ok || newFolderName.isEmpty())
        return; // 用户取消或没输入

    // 检查是否已经存在
    QDir dir(parentDir);
    if (dir.exists(newFolderName)) {
        QMessageBox::warning(this, "提示", "该文件夹已存在，请重新选择名字。");
        return;
    }

    // 创建新文件夹
    if (!dir.mkdir(newFolderName)) {
        QMessageBox::critical(this, "错误", "创建文件夹失败！");
        return;
    }

    QString projectDir = dir.filePath(newFolderName);
    projectManager->createProject(projectDir);
}


void MenuBar::loadProjectBtnClicked()
{
    QString projectDir = QFileDialog::getExistingDirectory(
        this,
        "选择项目目录",
        QDir::homePath(),
        QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks
    );

    if (projectDir.isEmpty())
        return;

    projectManager->openProject(projectDir);
}


void MenuBar::saveProjectBtnClicked()
{
    projectManager->saveProject();
}


void MenuBar::closeProjectBtnClicked()
{
    projectManager->closeProject();
}


void MenuBar::uploadMapBtnClicked()
{
    if(projectFolder.isEmpty())
    {
        return;
    }
    
    FileTransferDialog dlg;
    dlg.initialize(context);
    dlg.setTransMode(1);
    dlg.setGroundPath(projectFolder +"/map/preview.bag");
    dlg.setAirPath("preview.bag");
    // dlg.startTransfer();
    dlg.exec();
}


void MenuBar::uploadMissionBtnClicked()
{
    if(projectFolder.isEmpty()) {
        return;
    }

    // 打包文件
    QString missionDir = projectFolder +"/mission/";
    QString packFile = projectFolder +"/mission/mission-1.tar.gz";
    bool packRet = packJsonFiles(missionDir, packFile);
    if(!packRet) {
        return;
    }

    // 上传任务包
    FileTransferDialog dlg;
    dlg.initialize(context);
    dlg.setTransMode(1);
    dlg.setGroundPath(packFile);
    dlg.setAirPath("mission-1.tar.gz");
    int dlgRet = dlg.exec();
    if(dlgRet != QDialog::Accepted) {
        return;
    }

    // 调用service通知无人机端任务名称
    auto request = std::make_shared<MissionCfg::Request>();
    request->cfg_cmd = 1;
    request->drone_id = -1;
    request->mission_name = "mission-1";

    bool isServiceValid = missionCfgClient->wait_for_service(0.5s);
    if(!isServiceValid) {
        RCLCPP_WARN(rclcpp::get_logger("rclcpp"), "opr service not available...");
        return;
    }

    missionCfgClient->async_send_request(
        request,
        [this](rclcpp::Client<MissionCfg>::SharedFuture future)
        {
            auto response = future.get();
            if(response->result != 512) 
            {
                RCLCPP_WARN(rclcpp::get_logger("rclcpp"), "snapshot failed");
                return;
            }
            QMessageBox::information(this, "提示", "任务上传完成");
        }
    );  
}


bool MenuBar::packJsonFiles(const QString& sourceDirPath, const QString& outputFilePath) {
    QDir sourceDir(sourceDirPath);
    if (!sourceDir.exists()) {
        return false;
    }

    // 获取所有.json文件
    QStringList jsonFiles = sourceDir.entryList(QStringList() << "*.json", QDir::Files | QDir::Readable);
    if (jsonFiles.isEmpty()) {
        return false;
    }

    // 构建tar命令参数
    QProcess tarProcess;
    QStringList arguments;
    // -czvf: 创建(c) gzip压缩(z) 显示详细文件列表(v) 指定压缩文件名(f)
    arguments << "-czvf" << outputFilePath; 
    
    // 添加所有JSON文件名（不包含路径，因为setWorkingDirectory已设置）
    arguments << jsonFiles;

    // 在源目录下执行打包命令（确保tar命令使用相对路径时能正确找到文件）
    tarProcess.setWorkingDirectory(sourceDirPath);
    tarProcess.start("tar", arguments);

    // 等待命令执行完成（设置超时时间，例如3秒）
    if (!tarProcess.waitForFinished(3000)) {
        return false;
    }

    // 检查执行结果
    if (tarProcess.exitCode() != 0) {
        return false;
    }

    return true;
}


void MenuBar::snapshotBtnClicked()
{
    auto request = std::make_shared<ControlCmd::Request>();
    request->opr_cmd = 20;
    request->param_int = 1;
    request->drone_id = -1;

    bool isServiceValid = oprCmdClient->wait_for_service(0.5s);
    if(!isServiceValid) {
        RCLCPP_WARN(rclcpp::get_logger("rclcpp"), "opr service not available...");
        return;
    }

    oprCmdClient->async_send_request(
        request,
        [this](rclcpp::Client<ControlCmd>::SharedFuture future)
        {
            auto response = future.get();
            if(response->result != 512) 
            {
                RCLCPP_WARN(rclcpp::get_logger("rclcpp"), "snapshot failed");
                return;
            }
        }
    );   
}


void MenuBar::handleProjectLoaded(QSharedPointer<QVariantMap> projectData)
{
    QString projectDir = (*projectData)["projectDir"].toString();
    projectFolder = projectDir;
}


void MenuBar::handleProjectClosed(QSharedPointer<QVariantMap> projectData)
{
    projectFolder.clear();
}

}

}